/**
 * @file    list.c
 * @author  yang weikang
 * @brief   双向链表 参考链接:https://blog.csdn.net/k666499436/article/details/124787990    https://blog.csdn.net/k666499436/article/details/126759408?spm=1001.2014.3001.5501
 * @version 0.1	缺陷:线程不安全,如果使用操作系统需要使用者在外部加锁或者进入临界区 yangweikang	2023-07-14
 * @date    2023-07-14
 * 
 * @copyright Copyright (c) 2023..
 */
#include "list.h"
#include "stdio.h"
#include "stdlib.h"
#include "stddef.h"


/**
 * @brief   创建新节点
 * 
 * @param   data        
 * @return  ListNode* 新节点地址
 */
ListNode* CreateListNode(void)
{
	ListNode* NewNode = (ListNode*)list_malloc(sizeof(ListNode));
	if(NewNode ==NULL)
	    return NULL;
	NewNode->next = NULL;
	NewNode->prev = NULL;
    return NewNode;
}

/**
 * @brief   初始化链表
 * 
 * @return  ListNode* 链表对象
 */
ListNode* ListInit(void)
{
	ListNode* phead = CreateListNode();//创建头节点
	if(phead ==NULL)
	    return NULL;
	phead->next = phead;
	phead->prev = phead;
	
	return phead; 
}

/**
 * @brief   销毁链表对象
 * 
 * @param   pphead      链表对象的地址
 */
void ListDestory(ListNode** pphead)
{
	list_assert(pphead != NULL);
	list_assert(*pphead != NULL);

	ListNode* cur = (*pphead)->next;
	
	while(cur != *pphead)
	{
		ListNode* next = cur->next ;
        list_free(cur);
        cur = next;
	}
    list_free(*pphead);//释放头节点 
    *pphead = NULL;
}

/**
 * @brief   清空链表，不会释放头节点
 * 
 * @param   phead       链表对象
 */
void ListClear(ListNode* phead)
{
	list_assert(phead != NULL);

	ListNode* cur = phead->next;
    while(cur != phead)
	{
		ListNode* next = cur->next;
        list_free(cur);
        cur = next;
	}
	phead->next = phead;
	phead->prev = phead;
}

/**
 * @brief   打印链表
 * 
 * @param   phead       链表对象
 */
void Listprint(ListNode* phead)
{
	list_assert(phead != NULL);

	ListNode* cur = phead->next ;
	while(cur != phead)
	{
		list_printf("%p ",cur);
		cur = cur->next ;
	}
	list_printf("NULL\r\n");
}

/**
 * @brief   尾部插入节点
 * 
 * @param   phead       链表对象
 * @param   data        待插入的数据
 * @return	uint8_t		0:插入成功 1:插入失败，内存申请失败
 */
uint8_t ListPushBack(ListNode* phead, ListNode* NewNode)
{
	list_assert(phead != NULL);
	list_assert(NewNode != NULL);
	
    ListNode* tail = phead->prev;

	tail->next = NewNode;
	NewNode->prev = tail;
	NewNode->next = phead;
	phead->prev = NewNode;

	return 0;
 } 

/**
 * @brief   头部插入节点
 * 
 * @param   phead       链表对象
 * @param   data        待插入的数据
 * @return	uint8_t		0:插入成功 1:插入失败，内存申请失败
 */
 uint8_t ListPushFront(ListNode* phead, ListNode* NewNode)
 {
	list_assert(phead != NULL);//断言有头节点 
	list_assert(NewNode != NULL);

    ListNode* first = phead->next;
	phead->next =  NewNode;
	NewNode->next = first;
	NewNode->prev = phead;
	first->prev = NewNode;

	return 0;	
 }

/**
* @brief   删除尾部节点
* 
* @param   phead      链表对象 
* @return  uint8_t	  0:删除成功 1:删除失败，不存在数据节点
*/
 uint8_t ListPopBack(ListNode* phead)
 {
    list_assert(phead != NULL);//断言有头节点 
    if(phead->next == phead) //断言有数据节点
		return 1;
    
	ListNode* tail = phead->prev ;//找到尾节点 
	ListNode* tail_prev = tail->prev ;//尾节点 的前一个节点 
	tail_prev->next = phead;
	phead->prev = tail_prev;
	list_free(tail);
	return 0;
 }
 
/**
 * @brief   删除头部节点
 * 
 * @param   phead     链表对象  
 * @return  uint8_t	  0:删除成功 1:删除失败，不存在数据节点 
 */
 uint8_t ListPopFront(ListNode* phead)
 {
    list_assert(phead != NULL);//断言有头节点 
    if(phead->next == phead) //断言有数据节点
		return 1;
    
	ListNode* first = phead->next ;//找到首元节点 
	ListNode* second =  first->next ;//找到第二个数据节点 
	
	phead->next =  second;
	second->prev = phead;
	list_free(first);
	return 0;
 }
 
// /**
//  * @brief   查找值为data的节点
//  * 
//  * @param   phead       链表对象
//  * @param   data        待查找的值
//  * @return  ListNode* 	值为data的节点地址
//  */
// ListNode* ListFind(ListNode* phead, LTDataType data)
// {
// 	list_assert(phead != NULL);//断言有头节点
	
// 	ListNode* cur = phead->next;
// 	while(cur != phead)
// 	{
// 		if(cur->data == data)
// 		    return cur;
//         cur = cur->next;
// 	}
// 	return NULL;//没有找到返回NULL 
// }

/**
 * @brief   在pos指针指向的节点前插入一个节点
 * 
 * @param   phead       链表对象
 * @param   pos         被插入的节点
 * @param   NewNode     待插入的节点
 * @return  uint8_t	  	0:插入成功 1:插入失败，内存申请失败  
 */
uint8_t ListInsert(ListNode* phead, ListNode* pos, ListNode* NewNode)
{
	list_assert(phead != NULL);//断言有头节点
	list_assert(pos != NULL);
	list_assert(NewNode != NULL);

	ListNode* prev = pos->prev ;
	prev->next = NewNode;
	NewNode->prev = prev;
	NewNode->next = pos;
	pos->prev = NewNode;

	return 0;
}

/**
 * @brief   删除pos指针指向的结点
 * 
 * @param   phead       链表对象
 * @param   pos         待删除的节点
 */
uint8_t ListErase(ListNode* phead, ListNode** pos)
{
	list_assert(phead != NULL);//断言有头节点
	list_assert(pos != NULL);
	
	if(*pos == phead)//不能删除头节点 
		return 1;
	
	ListNode* prev = (*pos)->prev ;
	ListNode* next = (*pos)->next ;
	
	prev->next = next;
	next->prev = prev;
	list_free(*pos);
	*pos = NULL;

	return 0;
}

/**
 * @brief   计算链表长度
 * 
 * @param   phead       链表对象
 * @return  int 		链表长度
 */
int ListLength(ListNode* phead)
{
	list_assert(phead != NULL);//断言有头节点
	
	int len = 0; 
	ListNode* cur = phead->next ;
	
	while(cur != phead)
	{
		len++;
		cur = cur->next ;
	}
	return len;
}
